﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Sinacor.Infra.UI.Controls.SmartClient;
using System.Windows.Controls;
using Sinacor.Infra.UI.Authentication.Providers.Infra.Authorization.User;
using Sinacor.Infra.UI.Security.Services;
using Sinacor.Infra.Common.Security.Cryptography;

namespace Sinacor.Infra.UI.Authentication.Providers
{
    public class SinacorWindowChangePassword : Sinacor.Infra.UI.Controls.SmartClient.SinacorWindowChangePassword
    {
        private SinacorButton btnOk = null;
        private SinacorButton btnCancel = null;
        private SinacorButton btnClose = null;
        private PasswordBox txtPassword = null;
        private PasswordBox txtNewPassword = null;
        private PasswordBox txtConfirmNewPassword = null;
        private SinacorExpanderContainer expHeader = null;
        private string _password = null;

        /// <summary>
        /// Dependency property utilizada para fazer bind com o textbox da senha atual
        /// </summary>
        public string Password
        {
            get { return txtPassword.Password.Trim(); }
            set { txtPassword.Password = value; }
        }

        /// <summary>
        /// Dependency property utilizada para fazer bind com o textbox da nova senha
        /// </summary>
        public string NewPassword
        {
            get { return txtNewPassword.Password.Trim(); }
        }

        /// <summary>
        /// Dependency property utilizada para fazer bind com o textbox de confirmação da nova senha
        /// </summary>
        public string ConfirmNewPassword
        {
            get { return txtConfirmNewPassword.Password.Trim(); }
        }

        /// <summary>
        /// Construtor da janela, recebe o login do usuário e preenche a property Login, assim ela será exibida no label de login
        /// </summary>
        /// <param name="login"></param>
        public SinacorWindowChangePassword(string login)
        {
            this.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterScreen;
            this.SetResourceReference(StyleProperty, "ControlWindowChangePassword");

            this.Login = login;
        }

        /// <summary>
        /// Construtor da janela, recebe o login do usuário e preenche a property Login, assim ela será exibida no label de login. Recebe também a senha atual do usuário e preenche a property Password, assim ela será exibida no textbox da senha atual.
        /// </summary>
        /// <param name="login"></param>
        /// <param name="password"></param>
        public SinacorWindowChangePassword(string login, string password)
            : this(login)
        {
            _password = password;
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            btnOk = this.Template.FindName("btnOk", this) as SinacorButton;
            btnCancel = this.Template.FindName("btnCancel", this) as SinacorButton;
            btnClose = this.Template.FindName("btnClose", this) as SinacorButton;

            txtPassword = this.Template.FindName("txtPassword", this) as PasswordBox;
            txtNewPassword = this.Template.FindName("txtNewPassword", this) as PasswordBox;
            txtConfirmNewPassword = this.Template.FindName("txtConfirmNewPassword", this) as PasswordBox;

            expHeader = this.Template.FindName("expHeader", this) as SinacorExpanderContainer;
            expHeader.MouseLeftButtonDown += new System.Windows.Input.MouseButtonEventHandler(expHeader_MouseLeftButtonDown);

            btnOk.Click += new System.Windows.RoutedEventHandler(btnOk_Click);
            btnCancel.Click += new System.Windows.RoutedEventHandler(btnCancel_Click);
            btnClose.Click += new System.Windows.RoutedEventHandler(btnCancel_Click);

            txtPassword.Password = _password;
        }

        private void btnOk_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            if (String.IsNullOrEmpty(this.Password))
            {
                string message = FindResource("Infra.Application.Message.CurrentPasswordIsEmpty").ToString();
                SinacorMessageBox.Show(message, SinacorMessageBoxButton.Ok, SinacorMessageBoxImage.Exclamation);
                txtPassword.Focus();
            }
            else if (String.IsNullOrEmpty(this.NewPassword))
            {
                string message = FindResource("Infra.Application.Message.NewPasswordIsEmpty").ToString();
                SinacorMessageBox.Show(message, SinacorMessageBoxButton.Ok, SinacorMessageBoxImage.Exclamation);
                txtNewPassword.Focus();
            }
            else if (String.IsNullOrEmpty(this.ConfirmNewPassword))
            {
                string message = FindResource("Infra.Application.Message.ConfirmNewPasswordIsEmpty").ToString();
                SinacorMessageBox.Show(message, SinacorMessageBoxButton.Ok, SinacorMessageBoxImage.Exclamation);
                txtConfirmNewPassword.Focus();
            }
            else if (this.Password == this.NewPassword)
            {
                this.ShowInvalidNewPassword();
            }
            else if (this.NewPassword != this.ConfirmNewPassword)
            {
                this.ShowInvalidConfirmPassword();
            }
            else if (!this.ChangePassword())
            {
                this.ShowInvalidPassword();
            }
            else
            {
                this.ShowPasswordChanged();
                this.DialogResult = true;
                this.Close();
            }
        }

        private void btnCancel_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            this.Close();
        }

        private void expHeader_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            this.DragMove();
        }

        private bool ChangePassword()
        {
            using (ServiceInstance<IUser> si = new ServiceInstance<IUser>())
            {
                IUser service = si.TryGetInstanceWithoutSecurity();

                ChangePasswordRequest request = new ChangePasswordRequest() 
                { 
                    Login = this.Login,
                    Password = this.Password,
                    NewPassword = this.NewPassword
                };

                ChangePasswordResponse response = service.ChangePassword(request);
                return response.PasswordChanged;
            }
        }

        /// <summary>
        /// Exibe a mesagem de erro de senha atual inválida "Senha atual inválida"
        /// </summary>
        private void ShowInvalidPassword()
        {
            string message = FindResource("Infra.Application.Message.InvalidCurrentPassword").ToString();
            SinacorMessageBox.Show(message, SinacorMessageBoxButton.Ok, SinacorMessageBoxImage.Exclamation);
            txtPassword.Focus();
        }

        /// <summary>
        /// Exibe a mesagem de erro de nova senha inválida "A nova senha não pode ser igual a senha atual"
        /// </summary>
        private void ShowInvalidNewPassword()
        {
            string message = FindResource("Infra.Application.Message.InvalidNewPassword").ToString();
            SinacorMessageBox.Show(message, SinacorMessageBoxButton.Ok, SinacorMessageBoxImage.Exclamation);
            txtNewPassword.Focus();
        }

        /// <summary>
        /// Exibe a mesagem de erro de confirmação de nova senha inválida "A nova senha e a confirmação da nova senha precisam ser iguais"
        /// </summary>
        private void ShowInvalidConfirmPassword()
        {
            string message = FindResource("Infra.Application.Message.InvalidConfirmPassword").ToString();
            SinacorMessageBox.Show(message, SinacorMessageBoxButton.Ok, SinacorMessageBoxImage.Exclamation);
            txtConfirmNewPassword.Focus();
        }

        /// <summary>
        /// Exibe a mensagem de password alterado com sucesso "Senha alterada com sucesso"
        /// </summary>
        private void ShowPasswordChanged()
        {
            string message = FindResource("Infra.Application.Message.PasswordChanged").ToString();
            SinacorMessageBox.Show(message, SinacorMessageBoxButton.Ok, SinacorMessageBoxImage.Information);
        }
    }
}
